﻿using System;
using System.Data;
using System.Linq;
using System.Xml.Linq;
using System.Xml.XPath;
using PengSW.NotifyPropertyChanged;
using PengSW.ObservableCollectionHelper;
using PengSW.XmlHelper;
using static PengSW.XmlHelper.XmlLinqHelper;

namespace PengSW.XmlImport
{
    public class TableDefine : NotifyPropertyChangedObject, IXmlSeriable
    {
        public TableDefine(ImportRule aImportRule)
        {
            ImportRule = aImportRule;
        }

        public ImportRule ImportRule { get; }

        public string SourceTable { get { return _SourceTable; } set { SetValue(ref _SourceTable, value, nameof(SourceTable)); } }
        private string _SourceTable;

        public ObservableCollectionEx<RecordDefine> RecordDefines { get; } = new ObservableCollectionEx<RecordDefine>();

        public XElement CreateXElement(string aXmlNodeName)
        {
            return new XElement(aXmlNodeName,
                CreateXAttribute(nameof(SourceTable), SourceTable),
                from r in RecordDefines select r.CreateXElement(nameof(RecordDefine)));
        }

        public void ReadFromXml(XElement aXElement)
        {
            if (aXElement == null) return;
            SourceTable = aXElement.GetAttributeValue(nameof(SourceTable), null);

            // RecordDefines.Clear();
            foreach (XElement aRecordDefineXElement in aXElement.Elements(nameof(RecordDefine)))
            {
                RecordDefine aRecordDefine = new RecordDefine(this);
                aRecordDefine.ReadFromXml(aRecordDefineXElement);
                RecordDefines.Add(aRecordDefine);
            }
        }

        private XElement GetTableXElement(XElement aXElement)
        {
            XElement aTableXElement = aXElement.XPathSelectElement(SourceTable);
            if (aTableXElement != null) return aTableXElement;
            string aTableXPath = $"Table[@Id=\"{SourceTable}\"]";
            return aXElement.XPathSelectElement(aTableXPath);
        }

        public DataTable Import(XElement aXElement)
        {
            if (aXElement == null) throw new ApplicationException("无效的XElement");
            if (RecordDefines.Count == 0) throw new ApplicationException("未定义记录导入规则！");

            XElement aTableXElement = GetTableXElement(aXElement);
            if (aTableXElement == null) throw new ApplicationException("没有提取到有效的数据表！");

            DataTable aTable = new DataTable("Import");
            foreach (RecordDefine aRecordDefine in RecordDefines)
            {
                aRecordDefine.Import(aTable, aTableXElement);
            }
            return aTable;
        }
    }
}
